home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianVisMesh.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  21KB  |  795 lines

  1. /*ScianVisMesh.c
  2.   June 14, 1991
  3.   Eric Pepke
  4.   Routines for mesh visualization object
  5.  
  6.   The mesh object takes a scalar field defined over a data form with
  7.   topological dimension 2.  The spatial dimension of the dataset may be 
  8.   either 2 or 3.  If the spatial dimension is 2, the Z is assumed to be
  9.   zero.  The mesh visualization object works for regular data forms,
  10.   curvilinear data forms, and nonstructured data forms.
  11.  
  12. */
  13.  
  14. #include "Scian.h"
  15. #include "ScianTypes.h"
  16. #include "ScianArrays.h"
  17. #include "ScianWindows.h"
  18. #include "ScianTextBoxes.h"
  19. #include "ScianObjWindows.h"
  20. #include "ScianEvents.h"
  21. #include "ScianIcons.h"
  22. #include "ScianColors.h"
  23. #include "ScianControls.h"
  24. #include "ScianLists.h"
  25. #include "ScianSpaces.h"
  26. #include "ScianSliders.h"
  27. #include "ScianIDs.h"
  28. #include "ScianDatasets.h"
  29. #include "ScianErrors.h"
  30. #include "ScianVisObjects.h"
  31. #include "ScianVisMesh.h"
  32. #include "ScianStyle.h"
  33. #include "ScianPictures.h"
  34. #include "ScianTitleBoxes.h"
  35. #include "ScianButtons.h"
  36. #include "ScianMethods.h"
  37. #include "ScianDraw.h"
  38.  
  39. ObjPtr meshClass;
  40.  
  41. /*Values for color cells.  Don't change these values.*/
  42. #define COLORCELLSNONE        0
  43. #define COLORCELLSGRID        1
  44. #define COLORCELLSDATA        2
  45.  
  46. static ObjPtr MeshInit(object)
  47. ObjPtr object;
  48. /*Initializes a mesh object*/
  49. {
  50.     ObjPtr minMax;
  51.     real bounds[6];
  52.     real xySize, zSize;
  53.     ObjPtr colorObj, deformObj, mainDataset;
  54.     int nComponents;
  55.  
  56.     MakeVar(object, MAINDATASET);
  57.     mainDataset = GetVar(object, MAINDATASET);
  58.  
  59.     SetVar(object, COLOROBJ, colorObj = mainDataset);
  60.     if (colorObj)
  61.     {
  62.     SetVar(object, COLORS, ObjTrue);
  63.     }
  64.     SetVar(object, COLORCELLS, NewInt(1));
  65.     SetVar(object, DEFORMOBJ, deformObj = mainDataset);
  66.  
  67.     /*Heuristically determine whether to displace Z*/
  68.     GetBounds(object, bounds);
  69.     xySize = bounds[1] - bounds[0];
  70.     xySize = MAX(xySize, bounds[3] - bounds[2]);
  71.     xySize = MAX(xySize, bounds[5] - bounds[4]);
  72.  
  73.     SetCurForm(FORMFIELD, deformObj);
  74.  
  75.     nComponents = GetNComponents(FORMFIELD);
  76.  
  77.     if (nComponents < 3)
  78.     {
  79.     MakeVar(deformObj, MINMAX);
  80.     minMax = GetVar(deformObj, MINMAX);
  81.     zSize = ((real *) ELEMENTS(minMax))[1] - ((real *) ELEMENTS(minMax))[0];
  82.     if (zSize < xySize * 0.5)
  83.     {
  84.     SetVar(object, DEFORMSWITCH, NewInt(1));
  85.     }
  86.     else
  87.     {
  88.     SetVar(object, DEFORMSWITCH, NewInt(0));
  89.     }
  90.     }
  91.     else
  92.     {
  93.     SetVar(object, DEFORMSWITCH, NewInt(0));
  94.     }
  95.     return ObjTrue;
  96. }
  97.  
  98. static void DrawMajorMark(x, yt, yb, selected)
  99. int x, yt, yb;
  100. Bool selected;
  101. /*Draws a major mark at x from yt to yb.  Selected if selected.*/
  102. {
  103.     DrawUILine(x, yt - CCMARKBUTLEN, x, yb, UIBLACK);
  104.  
  105.     FillUIRect(x - CCMARKBUTWIDTH / 2, x + CCMARKBUTWIDTH / 2,
  106.         yt - CCMARKBUTLEN, yt, UIWHITE);
  107.     if (selected)
  108.     {
  109.     FrameUIRect(x - CCMARKBUTWIDTH / 2, x + CCMARKBUTWIDTH / 2 + 1,
  110.             yt - CCMARKBUTLEN - 1, yt, UIBLACK);
  111.     FrameUIRect(x - CCMARKBUTWIDTH / 2 - 1, x + CCMARKBUTWIDTH / 2 - 1,
  112.             yt - CCMARKBUTLEN + 1, yt + 1, UIYELLOW);
  113.     FrameUIRect(x - CCMARKBUTWIDTH / 2 - 2, x + CCMARKBUTWIDTH / 2,
  114.             yt - CCMARKBUTLEN, yt + 2, UIYELLOW);
  115.     }
  116.     else
  117.     {
  118.     FrameUIRect(x - CCMARKBUTWIDTH / 2, x + CCMARKBUTWIDTH / 2,
  119.             yt - CCMARKBUTLEN, yt, UIBLACK);
  120.     }
  121. }
  122.  
  123.  
  124. static ObjPtr SetMeshMainDataset(visObj, dataSet)
  125. ObjPtr visObj, dataSet;
  126. /*Sets the main data set of visObj to dataSet*/
  127. {
  128.     SetVar(visObj, MAINDATASET, dataSet);
  129.     return ObjTrue;
  130. }
  131.  
  132. static ObjPtr MakeMeshColored(visObject)
  133. ObjPtr visObject;
  134. /*Makes the mesh colored*/
  135. {
  136.     SetVar(visObject, PICCOLORED, ObjTrue);
  137.     if (GetPredicate(visObject, COLORS))
  138.     {
  139.     ObjPtr meshField;
  140.     ObjPtr colorField;
  141.     ObjPtr var;
  142.     ObjPtr surface;
  143.     ObjPtr palette;
  144.  
  145.     /*Get the mesh field and its form*/
  146.     meshField = GetObjectVar("MakeMeshColored", visObject, MAINDATASET);
  147.     if (!meshField) return ObjFalse;
  148.  
  149.     /*Get the color field and its form*/
  150.     colorField = GetObjectVar("MakeMeshColored", visObject, COLOROBJ);
  151.     if (!colorField) return ObjFalse;
  152.  
  153.     /*Get the surface to color*/
  154.     MakeVar(visObject, SURFACE);
  155.     surface = GetPictureVar("MakeMeshColored", visObject, SURFACE);
  156.     if (!surface) return ObjFalse;
  157.  
  158.     /*See if the mesh form is the same as the color form*/
  159.     SetCurForm(FORMFIELD, meshField);
  160.     SetCurForm(FIELD2, colorField);
  161.  
  162.     MakeVar(visObject, CPALETTE);
  163.     palette = GetPaletteVar("MakeMeshColored", visObject, CPALETTE);
  164.     if (!palette)
  165.     {
  166.         return ObjFalse;
  167.     }
  168.     SetPalette(palette);
  169.  
  170.     if (IdenticalFields(FORMFIELD, FIELD2))
  171.     {
  172.         /*Yes!  It's easy and fast to traverse*/
  173.         long info;
  174.         info = GetDatasetInfo(colorField);
  175.  
  176.         if (info & DS_UNSTRUCTURED)
  177.         {
  178.         /*It's an unstructured data form*/
  179.         ObjPtr faces;            /*Faces of the dataform*/
  180.         PolysPtr polys;            /*The polygons in the surface*/
  181.         PolyPtr polyRunner;        /*The runner through the polys*/
  182.         ThingListPtr cellRunner;    /*The runner through the cells*/
  183.         ObjPtr field;            /*The field itself*/
  184.  
  185.         faces = GetDatasetKEdges(meshField, 2);
  186.         if (!faces)
  187.         {
  188.             return ObjFalse;
  189.         }
  190.  
  191.         /*Look in the polys of the picture*/
  192.         polys = (PolysPtr) ((PicPtr) surface) -> items;
  193.         if (!polys)
  194.         {
  195.             return ObjTrue;
  196.         }
  197.         if (polys -> item . type != POLYGONS)
  198.         {
  199.             ReportError("MakeMeshColored", "Malformed picture");
  200.             return ObjFalse;
  201.         }
  202.  
  203.         /*Get the data*/
  204.         if (!SetCurField(FIELD1, colorField))
  205.         {
  206.             return ObjFalse;
  207.         }
  208.  
  209.         cellRunner = LISTOF(faces);
  210.         polyRunner = polys -> polygons;  
  211.     
  212.         while (cellRunner)
  213.         {
  214.             ObjPtr array;
  215.             int k, d, i, index;
  216.             real *a;
  217.  
  218.             if (!polyRunner)
  219.             {
  220.             ReportError("MakeMeshColored", "Picture too short");
  221.             break;
  222.             }
  223.             array = cellRunner -> thing;
  224.             d = DIMS(array)[0];
  225.             a = ArrayMeat(array);
  226.  
  227.             if (d == polyRunner -> nVertices)
  228.             {
  229.             for (k = 0; k < d; ++k)
  230.             {
  231.                 /*Color the vertices of the polygon*/
  232.                 long indices[1];
  233.                 i = *a;
  234.                 indices[0] = i;
  235.                 index = GetRealColorIndex(
  236.                 SelectFieldScalar(FIELD1, indices));
  237.                 polyRunner -> vertices[k] -> colorIndex = index;
  238.                 ++a;
  239.             }
  240.             }
  241.             else
  242.             {
  243.             ReportError("MakeMeshColored", "Malformed polygon");
  244.             }
  245.  
  246.             cellRunner = cellRunner -> next;
  247.             polyRunner = (PolyPtr) polyRunner -> item . next;
  248.         }
  249.         if (cellRunner)
  250.         {
  251.             ReportError("MakeMeshColored", "Picture too long");
  252.         }
  253.         }
  254.         else
  255.         {
  256.         /*Same structured dataset*/
  257.         int topDim;
  258.         long curDim[2], iDims[2];
  259.         ObjPtr dims;
  260.         RectMeshPtr rectMesh;
  261.         real temp[3];
  262.         ObjPtr var;
  263.         int colorCells;
  264.         Bool reverse;
  265.  
  266.         /*It must have dimension 2*/
  267.         topDim = GetTopDim(meshField);
  268.         if (topDim != 2)
  269.         {
  270.             ReportError("MakeMeshColored", "Topological dimension must be 2.");
  271.             return ObjFalse;
  272.         }
  273.  
  274.         /*Get the actual topological dimensions dimension*/
  275.         dims = GetDatasetFormDims(meshField);
  276.         if (!dims || !IsRealArray(dims) || RANK(dims) != 1 || DIMS(dims)[0] != 2)
  277.         {
  278.             return ObjFalse;
  279.         }
  280.  
  281.         iDims[0] = ((real *) ELEMENTS(dims))[0];
  282.         iDims[1] = ((real *) ELEMENTS(dims))[1];
  283.  
  284.         /*Register the mesh field*/
  285.         if (!SetCurField(FIELD1, colorField))
  286.         {
  287.             return ObjFalse;
  288.         }
  289.  
  290.         /*See what kind of color cells it has*/
  291.         var = GetIntVar("MakeMeshColored", visObject, COLORCELLS);
  292.         if (var)
  293.         {
  294.             colorCells = GetInt(var);
  295.          }
  296.         else
  297.         {
  298.             colorCells = 1;
  299.         }
  300.         if (colorCells)
  301.         {
  302.             real sample;
  303.             VertexPtr v;
  304.  
  305.             int iDim, jDim;
  306.  
  307.             reverse = (GetPredicate(visObject, REVERSESENSE) ^
  308.                 GetPredicate(meshField, ISLEFTHANDED));
  309.  
  310.             if (reverse)
  311.             {
  312.             iDim = 1;
  313.             jDim = 0;
  314.             }
  315.             else
  316.             {
  317.             iDim = 0;
  318.             jDim = 1;
  319.             }
  320.  
  321.             /*Get the rectangular mesh*/
  322.             rectMesh = (RectMeshPtr) ((PicPtr) surface) -> items;
  323.             if (!rectMesh)
  324.             {
  325.             return ObjFalse;
  326.             }
  327.  
  328.             if (colorCells == COLORCELLSGRID)
  329.             {
  330.             /*Color cells between the grid lines*/
  331.  
  332.             for (curDim[iDim] = 0; curDim[iDim] < iDims[iDim]; ++curDim[iDim])
  333.             {
  334.                 for (curDim[jDim] = 0; curDim[jDim] < iDims[jDim]; ++curDim[jDim])
  335.                 {
  336.                 sample = SelectFieldScalar(FIELD1, curDim);
  337.                 v = RectMeshVertex(rectMesh, 
  338.                     curDim[iDim], curDim[jDim]);
  339.                 v -> colorIndex = GetRealColorIndex(sample);
  340.                 }
  341.             }
  342.  
  343.             InterpRectCenters(rectMesh);
  344.  
  345.             }
  346.             else if (colorCells == COLORCELLSDATA)
  347.             {
  348.             /*Color cells around the data points*/
  349.  
  350.             for (curDim[iDim] = 0; curDim[iDim] < iDims[iDim]; ++curDim[iDim])
  351.             {
  352.                 for (curDim[jDim] = 0; curDim[jDim] < iDims[jDim]; ++curDim[jDim])
  353.                 {
  354.                 sample = SelectFieldScalar(FIELD1, curDim);
  355.                 v = RectMeshCenter(rectMesh, 
  356.                     curDim[iDim], curDim[jDim]);
  357.                 v -> colorIndex = GetRealColorIndex(sample);
  358.                 }
  359.             }
  360.  
  361.             InterpRectVertices(rectMesh);
  362.             }
  363.         }
  364.         }
  365.     }
  366.     else
  367.     {
  368.         ColorPictureByObject(surface, colorField, GetPredicate(visObject, INTERPCOLORS));
  369.     }
  370.     }
  371.     SetVar(visObject, PICCOLORED, ObjTrue);
  372.     return ObjTrue;
  373. }
  374.  
  375. static ObjPtr MakeMeshSurface(visObject)
  376. ObjPtr visObject;
  377. /*Makes the surface in a mesh object.*/
  378. {
  379.     ObjPtr dataset;        /*The dataset the vis object represents*/
  380.     long datasetFlags;        /*Flags of the dataset*/
  381.     ObjPtr var;            /*Random variable*/
  382.     int colorCells;        /*What kind of color cells*/
  383.     ObjPtr picture;        /*The picture to be made*/
  384.  
  385.     dataset = GetObjectVar("MakeMeshSurface", visObject, MAINDATASET);
  386.     if (!dataset)
  387.     {
  388.     return ObjFalse;
  389.     }
  390.  
  391.     datasetFlags = GetDatasetInfo(dataset);
  392.  
  393.     if (0 == datasetFlags & DS_HASFORM)
  394.     {
  395.     ReportError("MakeMeshSurface", "No data form");
  396.     return ObjFalse;
  397.     }
  398.  
  399.     /*See what kind of color cells it has*/
  400.     var = GetIntVar("MakeMeshSurface", visObject, COLORCELLS);
  401.     if (var)
  402.     {
  403.     colorCells = GetInt(var);
  404.     }
  405.     else
  406.     {
  407.     colorCells = 1;
  408.     }
  409.  
  410.     /*Make the new picture*/
  411.     picture = NewPicture();
  412.     if (!picture) return ObjFalse;
  413.  
  414.     if (datasetFlags & DS_UNSTRUCTURED)
  415.     {
  416.     /*It's an unstructured dataset.*/
  417.     ObjPtr edges;            /*Edges of the dataform*/
  418.     ObjPtr faces;            /*Faces of the dataform*/
  419.     TwoReals *edgesArray;        /*Array of edges*/
  420.     PolysPtr polys;            /*The polygons in the surface*/
  421.     ThingListPtr runner;        /*The runner through the cells*/
  422.     VertexPtr *vertices;        /*Temporary holding place for vertices*/
  423.     long allocVertices;        /*Number of vertices allocated*/
  424.     long nVertices;            /*Total number of vertices*/
  425.     VertexPtr *indVertices;        /*Indirect vertices*/
  426.     long k;                /*Index into form*/
  427.     ObjPtr dims;            /*Dims of the dataset*/
  428.  
  429.     SetCurForm(FORMFIELD, dataset);
  430.  
  431.     dims = GetDatasetFormDims(dataset);
  432.     if (!dims)
  433.     {
  434.         ReportError("MakeMeshSurface", "No form dimensions");
  435.         return ObjFalse;
  436.     }
  437.     nVertices = *((real *) ELEMENTS(dims));
  438.  
  439.     edges = GetDatasetKEdges(dataset, 1);
  440.     if (!edges)
  441.     {
  442.         return ObjFalse;
  443.     }
  444.     edgesArray = (TwoReals *) ArrayMeat(edges);
  445.  
  446.     faces = GetDatasetKEdges(dataset, 2);
  447.     if (!faces)
  448.     {
  449.         return ObjFalse;
  450.     }
  451.  
  452.     if (colorCells)
  453.     {
  454.         /*Make the picture and set it up with one polys*/
  455.         polys = AppendPolysToPicture(picture);
  456.         if (!polys) return ObjFalse;
  457.  
  458.         indVertices = (VertexPtr *) Alloc(nVertices * sizeof(VertexPtr));
  459.         for (k = 0; k < nVertices; ++k)
  460.         {
  461.         indVertices[k] = NewVertex(picture, 0);
  462.         indVertices[k] -> position[0] = SelectFieldComponent(FORMFIELD, 0, &k);
  463.         indVertices[k] -> position[1] = SelectFieldComponent(FORMFIELD, 1, &k);
  464.         indVertices[k] -> position[2] = SelectFieldComponent(FORMFIELD, 2, &k);
  465.         }
  466.  
  467.         allocVertices = 20;
  468.         vertices = (VertexPtr *) Alloc(20 * sizeof(VertexPtr));
  469.         if (!vertices)
  470.         {
  471.         return ObjFalse;
  472.         }
  473.     
  474.         runner = LISTOF(faces);    
  475.         while (runner)
  476.         {
  477.         ObjPtr array;
  478.         int k, d, i;
  479.         real *a;
  480.  
  481.         array = runner -> thing;
  482.         d = DIMS(array)[0];
  483.         a = ArrayMeat(array);
  484.  
  485.         for (k = 0; k < d; ++k)
  486.         {
  487.             i = *a;
  488.             
  489.             if (k >= allocVertices)
  490.             {
  491.             allocVertices += 20;
  492.             vertices = (VertexPtr *) Realloc(vertices, allocVertices * sizeof(VertexPtr));
  493.             if (!vertices)
  494.             {
  495.                 return ObjFalse;
  496.             }
  497.             }
  498.             vertices[k] = indVertices[i];
  499.  
  500.             ++a;
  501.         }
  502.         /*DIKEO fix to do better vertex allocation*/
  503.         AppendSPolyToPolys(polys, d, vertices);
  504.  
  505.         runner = runner -> next;
  506.         }
  507.         Free(vertices);
  508.         Free(indVertices);
  509.     }
  510.     }
  511.     else
  512.     {
  513.     /*It's a structured dataset.*/
  514.     int topDim, nComponents;
  515.     long curDim[2], iDims[2];
  516.     ObjPtr dims;
  517.     RectMeshPtr rectMesh;
  518.     real temp[3];
  519.     int iDim, jDim;
  520.     Bool reverse;
  521.  
  522.     /*It must have dimension 2*/
  523.     topDim = GetTopDim(dataset);
  524.     if (topDim != 2)
  525.     {
  526.         ReportError("MakeMeshSurface", "Topological dimension must be 2.");
  527.         return ObjFalse;
  528.     }
  529.  
  530.     /*Get the actual topological dimensions*/
  531.     dims = GetDatasetFormDims(dataset);
  532.     if (!dims || !IsRealArray(dims) || RANK(dims) != 1 || DIMS(dims)[0] != 2)
  533.     {
  534.         ReportError("MakeMeshSurface", "No topological dimensions");
  535.         return ObjFalse;
  536.     }
  537.  
  538.     iDims[0] = ((real *) ELEMENTS(dims))[0];
  539.     iDims[1] = ((real *) ELEMENTS(dims))[1];
  540.  
  541.     /*Register the dataset and its dataform*/
  542.     if (!SetCurField(FIELD1, dataset))
  543.     {
  544.         return ObjFalse;
  545.     }
  546.     if (!SetCurForm(FIELD2, dataset))
  547.     {
  548.         return ObjFalse;
  549.     }
  550.  
  551.     reverse = (GetPredicate(visObject, REVERSESENSE) ^
  552.         GetPredicate(dataset, ISLEFTHANDED));
  553.  
  554.     if (reverse)
  555.     {
  556.         iDim = 1;
  557.         jDim = 0;
  558.     }
  559.     else
  560.     {
  561.         iDim = 0;
  562.         jDim = 1;
  563.     }
  564.  
  565.     if (colorCells)
  566.     {
  567.         /*Create the color cells*/
  568.         VertexPtr v;
  569.  
  570.         if (colorCells == COLORCELLSGRID)
  571.         {
  572.         /*Color cells between the grid lines*/
  573.     
  574.         /*Create a new rectangular mesh*/
  575.         rectMesh = AppendRectMeshToPicture(picture, iDims[iDim], iDims[jDim], false);
  576.         if (!rectMesh)
  577.         {
  578.             return ObjFalse;
  579.         }
  580.  
  581.         nComponents = GetNComponents(FIELD2);
  582.  
  583.         for (curDim[iDim] = 0; curDim[iDim] < iDims[iDim]; ++curDim[iDim])
  584.         {
  585.             for (curDim[jDim] = 0; curDim[jDim] < iDims[jDim]; ++curDim[jDim])
  586.             {
  587.             v = RectMeshVertex(rectMesh, curDim[iDim], curDim[jDim]);
  588.             v -> position[0] = SelectFieldComponent(FIELD2, 0, curDim);
  589.             v -> position[1] = SelectFieldComponent(FIELD2, 1, curDim);
  590.             v -> position[2] = nComponents >= 3 ? SelectFieldComponent(FIELD2, 2, curDim) : 0.0;
  591.             }
  592.         }
  593.         InterpRectCenters(rectMesh);
  594.         }
  595.         else if (colorCells == COLORCELLSDATA)
  596.         {
  597.         /*Color cells around the data points*/
  598.  
  599.         /*Create a new rectangular mesh*/
  600.         rectMesh = AppendRectMeshToPicture(picture, iDims[iDim] + 1, iDims[jDim] + 1, true);
  601.         if (!rectMesh)
  602.         {
  603.             return ObjFalse;
  604.         }
  605.  
  606.         nComponents = GetNComponents(FIELD2);
  607.  
  608.         for (curDim[iDim] = 0; curDim[iDim] < iDims[iDim]; ++curDim[iDim])
  609.         {
  610.             for (curDim[jDim] = 0; curDim[jDim] < iDims[jDim]; ++curDim[jDim])
  611.             {
  612.             v = RectMeshCenter(rectMesh, curDim[iDim], curDim[jDim]);
  613.             v -> position[0] = SelectFieldComponent(FIELD2, 0, curDim);
  614.             v -> position[1] = SelectFieldComponent(FIELD2, 1, curDim);
  615.             v -> position[2] = nComponents >= 3 ? SelectFieldComponent(FIELD2, 2, curDim) : 0.0;
  616.             }
  617.         }
  618.         InterpRectVertices(rectMesh);
  619.         }
  620.     }
  621.     }
  622.  
  623.     CalcPictureNormals(picture);
  624.     SetVar(visObject, SURFACE, picture);
  625.     SetVar(picture, REPOBJ, visObject);
  626.     return ObjTrue;
  627. }
  628.  
  629. static ObjPtr AddMeshControls(mesh, panelContents)
  630. ObjPtr mesh, panelContents;
  631. /*Adds controls appropriate to a mesh object to panelContents*/
  632. {
  633.     ObjPtr titleBox, button, radio, var, corral, icon, name, meshField, mainDataset;
  634.     ObjPtr textBox, defaultIcon;
  635.     int width, left, top, bottom, right;
  636.     ObjPtr control;
  637.     ObjPtr minMax;
  638.     real min, max, *elements;
  639.  
  640.     width = CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH;
  641.  
  642.     /*Get the mesh field*/
  643.     meshField = GetObjectVar("AddMeshControls", mesh, MAINDATASET);
  644.     if (!meshField) return ObjFalse;
  645.     while (mainDataset = GetVar(meshField, MAINDATASET))
  646.     {
  647.     meshField = mainDataset;
  648.     }
  649.  
  650.     /*Find its min and max*/
  651.     MakeVar(meshField, MINMAX);
  652.     minMax = GetVar(meshField, MINMAX);
  653.     if (minMax)
  654.     {
  655.     elements = ELEMENTS(minMax);
  656.     min = elements[0];
  657.     max = elements[1];
  658.     }
  659.     else
  660.     {
  661.     min = 0.0;
  662.     max = 1.0;
  663.     }
  664.  
  665.     /*Create the color cells title box*/
  666.     right = width;
  667.     left = right - (CCBUTTONLENGTH + 2 * MINORBORDER);
  668.     top = CWINHEIGHT - MINORBORDER;
  669.     bottom = top - (2 * MINORBORDER + 3 * CHECKBOXHEIGHT + 2 * CHECKBOXSPACING + TITLEBOXTOP);
  670.  
  671.     titleBox = NewTitleBox(left, right, bottom, top, "Color Cells");
  672.     PrefixList(panelContents, titleBox);
  673.     SetVar(titleBox, PARENT, panelContents);
  674.  
  675.     /*Create the radio button group*/
  676.     radio = NewRadioButtonGroup("Color Cells Radio");
  677.     PrefixList(panelContents, radio);
  678.     SetVar(radio, PARENT, panelContents);
  679.  
  680.     /*Create the buttons*/
  681.     left += MINORBORDER;
  682.     right -= MINORBORDER;
  683.     top -= TITLEBOXTOP + MINORBORDER;
  684.     bottom = top - CHECKBOXHEIGHT;
  685.     button = NewRadioButton(left, right, bottom, top, "None");
  686.     AddRadioButton(radio, button);
  687.  
  688.     top = bottom - CHECKBOXSPACING;
  689.     bottom = top - CHECKBOXHEIGHT;
  690.     button = NewRadioButton(left, right, bottom, top, "Between Grid Lines");
  691.     AddRadioButton(radio, button);
  692.  
  693.     top = bottom - CHECKBOXSPACING;
  694.     bottom = top - CHECKBOXHEIGHT;
  695.     button = NewRadioButton(left, right, bottom, top, "Around Data Points");
  696.     AddRadioButton(radio, button);
  697.  
  698.     /*Set the radio according to COLORCELLS*/
  699.     var = GetIntVar("AddMeshControls", mesh, COLORCELLS);
  700.     if (!var)
  701.     {
  702.     SetVar(mesh, COLORCELLS, NewInt(1));
  703.     }
  704.     AssocDirectControlWithVar(radio, mesh, COLORCELLS);
  705.  
  706.     /*Put in the mesh corral at the top left*/
  707.     left = MAJORBORDER;
  708.     top = MAJORBORDER;
  709.     corral = NewIconCorral(NULLOBJ,
  710.                left, left + ONECORRALWIDTH,
  711.                CWINHEIGHT - MAJORBORDER - ONECORRALHEIGHT,
  712.                CWINHEIGHT - MAJORBORDER, 0);
  713.     SetVar(corral, SINGLECORRAL, ObjTrue);
  714.     SetVar(corral, TOPDOWN, ObjTrue);
  715.     SetVar(corral, NAME, NewString("Mesh Field"));
  716.     SetVar(corral, HELPSTRING,
  717.     NewString("This corral shows the dataset that is being used to make \
  718. the mesh display.  The locations of color cells and meshs are calculated \
  719. using this field.  The color of color cells is calculated using the Color Field, \
  720. available in the Color control set."));
  721.     PrefixList(panelContents, corral);
  722.     SetVar(corral, PARENT, panelContents);
  723.     SetVar(corral, REPOBJ, mesh);
  724.     SetMethod(corral, DROPINCONTENTS, DropInMainDatasetCorral);
  725.  
  726.     /*Create the mesh source text box*/
  727.     textBox = NewTextBox(left, left + ONECORRALWIDTH, 
  728.              CWINHEIGHT - MAJORBORDER - ONECORRALHEIGHT - TEXTBOXSEP - TEXTBOXHEIGHT,
  729.              CWINHEIGHT - MAJORBORDER - ONECORRALHEIGHT - TEXTBOXSEP,
  730.              0, "Mesh Field Text", "Mesh Field");
  731.     PrefixList(panelContents, textBox);
  732.     SetVar(textBox, PARENT, panelContents);
  733.     SetTextAlign(textBox, CENTERALIGN);
  734.  
  735.     /*Put in an icon that represents the field*/
  736.     name = GetVar(meshField, NAME);
  737.     defaultIcon = GetVar(meshField, DEFAULTICON);
  738.     if (defaultIcon)
  739.     {
  740.     icon = NewObject(defaultIcon, 0);
  741.     SetVar(icon, NAME, name);
  742.     }
  743.     else
  744.     {
  745.     icon = NewIcon(0, 0, ICONQUESTION, GetString(name));
  746.     }
  747.     SetVar(icon, ICONLOC, NULLOBJ);
  748.     SetVar(icon, REPOBJ, meshField);
  749.     DropIconInCorral(corral, icon);
  750.  
  751.     return ObjTrue;
  752. }
  753.  
  754. void InitMeshes()
  755. /*Initializes the mesh object*/
  756. {
  757.     ObjPtr icon, color;
  758.  
  759.     /*Class for a mesh object*/
  760.     meshClass = NewObject(visDeformed, 0);
  761.     AddToReferenceList(meshClass);
  762.     SetVar(meshClass, NAME, NewString("Mesh"));
  763.     SetMethod(meshClass, INITIALIZE, MeshInit);
  764.     SetVar(meshClass, SHINVAL, NewReal(80.0));
  765.     SetVar(meshClass, SPECVAL, NewReal(0.2));
  766.     SetVar(meshClass, DEFAULTICON, icon = NewObject(visIcon, 0));
  767.     SetVar(icon, WHICHICON, NewInt(ICONMESH));
  768.     SetVar(icon, NAME, NewString("Mesh"));
  769.     SetVar(icon, HELPSTRING,
  770.     NewString("This icon represents a mesh visualization object.  \
  771. The mesh object shows shaded mesh surfaces of 2-dimensional \
  772. scalar fields defined over structured or nonstructured grids."));
  773.     DeclareIndirectDependency(meshClass, SURFACE, MAINDATASET, CHANGED);
  774.     DeclareDependency(meshClass, SURFACE, COLORCELLS);
  775.     SetMethod(meshClass, SURFACE, MakeMeshSurface);
  776.     DeclareDependency(meshClass, SURFACE, REVERSESENSE);
  777.     SetMethod(meshClass, PICCOLORED, MakeMeshColored);
  778.     SetMethod(meshClass, SETMAINDATASET, SetMeshMainDataset);
  779.  
  780.     SetMethod(meshClass, ADDCONTROLS, AddMeshControls);
  781.     icon = NewIcon(0, 0, ICONMESH, "Mesh");
  782.     SetVar(meshClass, CONTROLICON, icon);
  783.  
  784.     DefineVisMapping(DS_HASFORM | DS_HASFIELD, 2, 3, 1, meshClass);
  785.     DefineVisMapping(DS_HASFORM | DS_HASFIELD, 2, 2, 1, meshClass);
  786.     DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_UNSTRUCTURED, 2, 3, 1, meshClass);
  787.     DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_UNSTRUCTURED, 2, 2, 1, meshClass);
  788. }
  789.  
  790. void KillMeshes()
  791. /*Kills the mesh*/
  792. {
  793.     DeleteThing(meshClass);
  794. }
  795.